home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
001-010
/
amok07
/
muchmore
/
muchmore.mod
< prev
next >
Wrap
Text File
|
1993-11-04
|
22KB
|
709 lines
(*---------------------------------------------------------------------------
:Program. MuchMore.mod
:Author. Fridtjof Siebert
:Address. Nobileweg 67, D-7-Stgt-40
:Phone. Please write a letter.
:Shortcut. [fbs]
:Version. 1.1
:Date. 24-Sep-88
:Copyright. PD
:Language. Modula-II
:Translator. M2Amiga
:Imports. WarpText [Bill Kelly, fbs]
:Imports. NTSC [fbs]
:UpDate. none.
:Contents. A Soft-Scrolling ASCII-File Printer.
:Remark. Usage: MuchMore {FileName(s)}
---------------------------------------------------------------------------*)
MODULE MuchMore;
(*----------------------------- IMPORTs: --------------------------------*)
(*------ SYSTEM: ------*)
FROM SYSTEM IMPORT ADR, ADDRESS, SHIFT;
FROM Arguments IMPORT NumArgs, GetArg;
FROM Arts IMPORT TermProcedure, Terminate, CurrentLevel, BreakPoint,
Assert;
(*------ Libraries: ------*)
FROM Dos IMPORT Open, Close, oldFile, Read, FileHandlePtr;
FROM Exec IMPORT GetMsg, ReplyMsg, MessagePtr, WaitPort, AllocMem,
FreeMem, MemReqSet, MemReqs;
FROM Graphics IMPORT SetAPen, SetDrMd, jam1, jam2, DrawModes, DrawModeSet,
Text, Draw, ViewModes, ViewModeSet, FontStyles,
FontStyleSet, FontFlags, FontFlagSet, TextAttr,
RastPortPtr, Move, BltBitMap, WaitBOVP, WaitTOF,
BitMap, InitBitMap, BltClear, OpenFont, CloseFont,
TextFontPtr, WaitBlit;
FROM InputEvent IMPORT Qualifiers, QualifierSet;
FROM Intuition IMPORT NewScreen, ScreenFlags, ScreenFlagSet, customScreen,
OpenScreen, CloseScreen, MakeScreen, RethinkDisplay,
ScreenPtr, NewWindow, WindowFlags, WindowFlagSet,
IDCMPFlags, IDCMPFlagSet, OpenWindow, CloseWindow,
WindowPtr, IntuiMessage, IntuiMessagePtr;
(*------ Standard: ------*)
FROM Strings IMPORT Length, Copy, first, last;
(*------ Other: ------*)
FROM NTSC IMPORT NTSC;
FROM WarpText IMPORT SetUpFont, NewWarp, NewWarpInfo;
(*------------------------------ TYPES: ---------------------------------*)
TYPE
TextLinePtr = POINTER TO TextLine;
TextLine = RECORD
next: TextLinePtr;
prev: TextLinePtr;
text: ARRAY[0..81] OF CHAR;
END;
(*----------------------------- Variables: ------------------------------*)
VAR
NuScreen: NewScreen;
Screen: ScreenPtr; (* Screen that contains the Text *)
RP: RastPortPtr; (* Screen's RastPort *)
NuWindow: NewWindow;
Window: WindowPtr;
MyFont: TextAttr;
retry: BOOLEAN; (* used for Retry/Cancel-Requesters *)
MyFile: FileHandlePtr; (* For loading Textfile *)
FirstLine: TextLinePtr; (* Saved Text *)
TopLine: TextLinePtr; (* Points to topmost Line *)
BottomLine: TextLinePtr; (* Last Line displayed on Screen *)
len: INTEGER; (* Length of Text's name *)
Name: ARRAY[0..127] OF CHAR; (* Text's Name *)
Buffer: POINTER TO ARRAY[0..511] OF CHAR; (* Buffer for Reading *)
RQPos: LONGINT; (* Position within ReadBuffer *)
RQLen: LONGINT; (* Number of CHARs in Buffer *)
EOF: BOOLEAN; (* End of File ? *)
CountFiles: INTEGER; (* Counts TextFiles *)
i: INTEGER; (* used in FOR-NEXT-loops *)
NumLines: INTEGER; (* Number of Lines (32 PAL, 25 NTSC) *)
BitMaps: ARRAY[0..1] OF BitMap; (* BitMaps for DoubleBuffering *)
DisplayedMap: [0..1]; (* actually displayed BitMap *)
AnzLines: INTEGER; (* Length of Text in Lines *)
Scroll: BOOLEAN; (* TRUE = Scroll, FALSE = Wait. *)
Down: BOOLEAN; (* Scroll-Direction *)
MyMsgPtr: IntuiMessagePtr; (* For receiving Messages *)
MyMsg: IntuiMessage; (* contains Message *)
Shift: BOOLEAN; (* Shifted Keystroke ? *)
Alt: BOOLEAN; (* Altered Keystroke ? *)
RefreshDisplayCnt: CARDINAL; (* Lines to output after HELP *)
Font: TextFontPtr; (* Font for WarpText *)
nwinfo: NewWarpInfo; (* Info for WarpText *)
(*------------------------ Open Display: --------------------------------*)
PROCEDURE InitScreen();
BEGIN
(*------ Open Screen: ------*)
WITH MyFont DO
name := ADR("topaz.font");
ySize := 8;
style := FontStyleSet{};
flags := FontFlagSet{};
END;
WITH nwinfo DO
fontData := AllocMem(2048,MemReqSet{memClear});
IF fontData=NIL THEN Terminate(0) END;
END;
Font := OpenFont(ADR(MyFont));
SetUpFont(ADR(nwinfo),Font);
WITH NuScreen DO
leftEdge := 0;
topEdge := 0;
width := 640;
IF NTSC() THEN
height := 216;
NumLines := 25;
ELSE
height := 272;
NumLines := 32;
END;
depth := 1;
detailPen := 0;
blockPen := 1;
viewModes := ViewModeSet{hires};
font := ADR(MyFont);
defaultTitle := NIL;
gadgets := NIL;
customBitMap := ADR(BitMaps[DisplayedMap]);
END;
NuScreen.type := customScreen + ScreenFlagSet{screenQuiet,customBitMap};
DisplayedMap := 0;
WITH NuScreen DO
REPEAT
InitBitMap(BitMaps[DisplayedMap],depth,width,height);
WITH BitMaps[DisplayedMap] DO
planes[0] := AllocMem(width DIV 8 * height,MemReqSet{chip,memClear});
IF planes[0]=NIL THEN Terminate(0) END;
END;
DisplayedMap := 1 - DisplayedMap;
UNTIL DisplayedMap = 0;
END;
Screen := OpenScreen(NuScreen);
Assert(Screen#NIL,ADR("OpenScrn failed !!"));
RP := ADR(Screen^.rastPort);
RP^.bitMap := ADR(BitMaps[1-DisplayedMap]);
DEC(Screen^.height,16);
INC(Screen^.viewPort.rasInfo^.ryOffset,8);
MakeScreen(Screen); RethinkDisplay();
(*------ Open Window: ------*)
WITH NuWindow DO
leftEdge := 0;
topEdge := 10;
width := 640;
height := Screen^.height-10;
detailPen := 0;
blockPen := 1;
idcmpFlags := IDCMPFlagSet{rawKey};
flags := WindowFlagSet{borderless,activate};
firstGadget:= NIL;
checkMark := NIL;
title := NIL;
screen := Screen;
bitMap := NIL;
minWidth := 0;
minHeight := 0;
maxWidth := -1;
maxHeight := -1;
type := customScreen;
END;
Window := OpenWindow(NuWindow);
Assert(Window#NIL,ADR("OpenWindow failed!!!"));
END InitScreen;
(*------ Flip Buffers: ------*)
PROCEDURE FlipBitMap();
BEGIN
RP^.bitMap := ADR(BitMaps[DisplayedMap]);
DisplayedMap := 1 - DisplayedMap;
Screen^.viewPort.rasInfo^.bitMap := ADR(BitMaps[DisplayedMap]);
MakeScreen(Screen); RethinkDisplay();
END FlipBitMap;
(*------ Read one TextLine into a Variable: ------*)
PROCEDURE GetTextLine(Line: TextLinePtr): BOOLEAN;
(* returns TRUE if EOF *)
VAR
Pos: CARDINAL;
BEGIN
Pos := 0;
WITH Line^ DO
text := " ";
LOOP
IF RQPos=RQLen THEN
RQLen := Read(MyFile,Buffer,SIZE(Buffer^));
RQPos := 0;
END;
text[Pos] := Buffer^[RQPos];
INC(RQPos);
IF text[Pos]<" " THEN
CASE ORD(text[Pos]) OF
09H: REPEAT
text[Pos] := " ";
INC(Pos);
UNTIL (Pos=80) OR (SHIFT(SHIFT(Pos,-3),3)=Pos);
DEC(Pos); |
0AH,0DH,0: EXIT; |
ELSE
text[Pos] := " ";
END;
END;
INC(Pos);
IF Pos>=80 THEN EXIT END;
END;
IF Pos#80 THEN text[Pos] := " " END;
END;
RETURN RQLen=0;
END GetTextLine;
(*------ Type one Line of Text: ------*)
PROCEDURE TypeLine(Line: TextLinePtr; PosY: INTEGER);
BEGIN
WITH Line^ DO
WITH nwinfo DO
bitPlane := RP^.bitMap^.planes[0];
xLoc := 0; yLoc := PosY;
WaitBlit();
NewWarp(ADR(nwinfo),ADR(text),80);
END;
END;
END TypeLine;
(*------ Write Line at Bottom of Text: ------*)
PROCEDURE AddBottomLine(Line: TextLinePtr; Fast: BOOLEAN);
VAR
Height: INTEGER;
i: INTEGER;
BEGIN
WITH Screen^ DO
TypeLine(Line,NumLines);
IF BltBitMap(ADR(BitMaps[1-DisplayedMap]),0,height,ADR(BitMaps[
DisplayedMap]),0,height+8,640,8,0C0H,1,NIL) = 0 THEN END;
WITH viewPort.rasInfo^ DO
IF Fast THEN
FlipBitMap();
IF BltBitMap(ADR(BitMaps[1-DisplayedMap]),0,16,ADR(BitMaps[1-
DisplayedMap]),0,0,width,height,0C0H,1,NIL) = 0 THEN END;
ELSE
DEC(ryOffset,7);
FlipBitMap();
Height := height DIV 4;
FOR i:=0 TO 3 DO
INC(ryOffset,1);
MakeScreen(Screen); RethinkDisplay();
IF BltBitMap(ADR(BitMaps[1-DisplayedMap]),0,16+i*Height,
ADR(BitMaps[1-DisplayedMap]),0,i*Height,
width,Height,0C0H,1,NIL) = 0 THEN END;
END;
FOR i:=4 TO 6 DO
INC(ryOffset,1);
MakeScreen(Screen); RethinkDisplay();
END;
END;
END;
END;
END AddBottomLine;
(*------ Write String to Screen: ------*)
PROCEDURE Write(String: ARRAY OF CHAR);
VAR
text: TextLine;
BEGIN
text.next := NIL;
text.prev := NIL;
text.text := " ";
Copy(text.text,String,0,Length(String));
text.text[Length(String)] := " ";
AddBottomLine(ADR(text),FALSE);
END Write;
(*------ Deallocate Text: ------*)
PROCEDURE FreeText(Text: TextLinePtr);
(* This was recursiv, but caused Stack overflow with 4K Stack *)
VAR
text: TextLinePtr;
BEGIN
IF Text#NIL THEN
WHILE Text^.next#NIL DO Text := Text^.next END;
WHILE Text^.prev#NIL DO
text := Text;
Text := Text^.prev;
FreeMem(text,SIZE(TextLine));
END;
FreeMem(Text,SIZE(TextLine));
END;
END FreeText;
(*------ Scroll down one Line: ------*)
PROCEDURE ScrollDown(Fast: BOOLEAN; Read: BOOLEAN): BOOLEAN;
(* Returns TRUE if EOF *)
VAR
EOF: BOOLEAN;
NewDisplay: BOOLEAN;
BEGIN
NewDisplay := TRUE;
IF (FirstLine=NIL) AND Read THEN
FirstLine := AllocMem(SIZE(TextLine),MemReqSet{memClear});
IF FirstLine=NIL THEN Terminate(0) END;
TopLine := FirstLine; BottomLine := FirstLine;
EOF := GetTextLine(BottomLine);
IF EOF THEN
FreeMem(FirstLine,SIZE(TextLine));
FirstLine := NIL;
NewDisplay := FALSE;
ELSE
INC(AnzLines);
END;
ELSIF (BottomLine^.next=NIL) AND Read THEN
BottomLine^.next := AllocMem(SIZE(TextLine),MemReqSet{memClear});
IF BottomLine^.next=NIL THEN Terminate(0) END;
BottomLine^.next^.prev := BottomLine;
BottomLine := BottomLine^.next;
EOF := GetTextLine(BottomLine);
IF EOF THEN
BottomLine := BottomLine^.prev;
FreeMem(BottomLine^.next,SIZE(TextLine));
BottomLine^.next := NIL;
NewDisplay := FALSE;
ELSE
INC(AnzLines);
END;
ELSIF (BottomLine^.next#NIL) AND (BottomLine#NIL) THEN
BottomLine := BottomLine^.next;
EOF := FALSE;
ELSE
NewDisplay := FALSE;
END;
IF NewDisplay THEN
IF (AnzLines>=NumLines) AND (RefreshDisplayCnt=0) THEN
TopLine := TopLine^.next;
END;
AddBottomLine(BottomLine,Fast);
END;
RETURN EOF;
END ScrollDown;
(*------ Scroll Up one Line: ------*)
PROCEDURE ScrollUp(Fast: BOOLEAN);
VAR
Height: INTEGER;
i: INTEGER;
BEGIN
IF (TopLine^.prev#NIL) AND (TopLine^.prev^.prev#NIL) THEN
TopLine := TopLine^.prev;
BottomLine := BottomLine^.prev;
WITH Screen^ DO
RP^.bitMap := ADR(BitMaps[DisplayedMap]);
WITH TopLine^ DO
TypeLine(prev,0);
IF Fast THEN
IF BltBitMap(ADR(BitMaps[1-DisplayedMap]),0, 0,
ADR(BitMaps[1-DisplayedMap]),0,16,
width,height-8,0C0H,1,NIL) = 0 THEN END;
ELSE
Height := (height-8) DIV 4;
WITH viewPort.rasInfo^ DO
IF NOT(Fast) THEN
FOR i:=1 TO 4 DO
DEC(ryOffset,1);
MakeScreen(Screen); RethinkDisplay(); (* WaitTOF(); *)
IF BltBitMap(ADR(BitMaps[1-DisplayedMap]),0,height-8-i*Height,
ADR(BitMaps[1-DisplayedMap]),0,height+8-i*Height,
width,Height,0C0H,1,NIL) = 0 THEN END;
END;
FOR i:=4 TO 6 DO
DEC(ryOffset,1);
MakeScreen(Screen); RethinkDisplay(); (* WaitTOF(); *)
END;
INC(ryOffset,7);
END;
END;
END; (* IF FAST THEN ELSE *)
END; (* WITH TopLine^ DO *)
IF BltBitMap(ADR(BitMaps[DisplayedMap]),0,0,
ADR(BitMaps[1-DisplayedMap]),0,8,
640,8,0C0H,1,NIL) = 0 THEN END;
FlipBitMap();
END; (* WITH Screen^ DO *)
END; (* IF TopLine#NIL ... *)
END ScrollUp;
(*------ Clear Display: ------*)
PROCEDURE ClearBitMaps();
BEGIN
WITH BitMaps[0] DO
BltClear(planes[0],bytesPerRow*rows,0);
END;
WITH BitMaps[1] DO
BltClear(planes[0],bytesPerRow*rows,0);
END;
END ClearBitMaps;
(*------ CleanUp: ------*)
PROCEDURE CleanUp();
BEGIN
IF Window#NIL THEN CloseWindow(Window) END;
IF Screen#NIL THEN CloseScreen(Screen) END;
WITH NuScreen DO
WITH BitMaps[0] DO
IF planes[0]#NIL THEN FreeMem(planes[0],width DIV 8 * height) END;
END;
WITH BitMaps[1] DO
IF planes[0]#NIL THEN FreeMem(planes[0],width DIV 8 * height) END;
END;
END;
IF Buffer#NIL THEN FreeMem(Buffer,SIZE(Buffer^)) END;
IF MyFile#NIL THEN Close(MyFile) END;
FreeText(FirstLine);
WITH nwinfo DO
IF fontData#NIL THEN FreeMem(fontData,2048) END;
END;
END CleanUp;
(*------------------------------ MAIN: ----------------------------------*)
BEGIN
(*------ Init: ------*)
Screen := NIL; Window := NIL; FirstLine := NIL; Buffer := NIL;
TopLine := NIL; BottomLine := NIL; MyFile := NIL; AnzLines := 0;
Scroll := TRUE; Down := TRUE; nwinfo.fontData := NIL;
TermProcedure(CleanUp);
InitScreen();
Buffer := AllocMem(SIZE(Buffer^),MemReqSet{chip,memClear});
IF Buffer=NIL THEN Terminate(0) END;
(*------ Open File(s): ------*)
IF NumArgs()=0 THEN
Write(" MuchMore");
Write(" =============="); Write("");
Write(" A Soft-Scrolling ASCII-File-Printer."); Write("");
Write(" Usage: "); Write("");
Write(" MuchMore {FileName(s)}"); Write("");
Write(" To Start from Workbench Shift-click Texts to Print before"); Write("");
Write(" doubleclicking MuchMore. "); Write("");
Write(" Texts whose Default Tool is MuchMore just need to be doubleclicked"); Write("");
Write(" This should work on NTSC as well as on PAL Amigas."); Write("");
Write(" © 1988 Fridtjof Siebert, Nobileweg 67, D-7000-Stuttgart-40");
Write(" Thanx to Bill Kelly for his WarpText-routines!"); Write("");
Write(" This is free to be spread on PD or Shareware Disks, as long as");
Write(" you leave my name in.");
Write(" It's illegal to make any profit of this without my permission !");
IF NOT(NTSC()) THEN
FOR i:=0 TO 6 DO Write(""); END;
END;
LOOP
WaitPort(Window^.userPort);
MyMsgPtr := ADDRESS(GetMsg(Window^.userPort));
IF MyMsgPtr^.code<128 THEN EXIT END;
ReplyMsg(MyMsgPtr);
END;
ReplyMsg(MyMsgPtr);
ELSE
CountFiles := 1;
LOOP
WHILE (CountFiles<=NumArgs()) AND (MyFile=NIL) DO
GetArg(CountFiles,Name,len);
MyFile := Open(ADR(Name),oldFile);
RQPos := -1; RQLen := -1;
INC(CountFiles);
END;
(*------ Type Text: ------*)
IF Scroll THEN
IF Down THEN
IF ScrollDown(FALSE,MyFile#NIL) THEN
Close(MyFile);
MyFile := NIL;
END;
IF RefreshDisplayCnt#0 THEN DEC(RefreshDisplayCnt) END;
ELSE
ScrollUp(FALSE);
END;
ELSE
WaitPort(Window^.userPort);
END;
MyMsgPtr := ADDRESS(GetMsg(Window^.userPort));
IF MyMsgPtr#NIL THEN
MyMsg := MyMsgPtr^;
ReplyMsg(MessagePtr(MyMsgPtr));
WITH MyMsg DO
IF class=IDCMPFlagSet{rawKey} THEN
Shift := (lShift IN QualifierSet(qualifier)) OR
(rShift IN QualifierSet(qualifier)) OR
(capsLock IN QualifierSet(qualifier));
Alt := (lAlt IN QualifierSet(qualifier)) OR
(rAlt IN QualifierSet(qualifier));
CASE code OF
40H: IF Down THEN (* Space *)
Scroll := NOT(Scroll);
IF (BottomLine^.next=NIL) AND (MyFile=NIL) THEN
EXIT;
END;
ELSE
Down := TRUE;
Scroll := TRUE;
END; |
41H: IF RefreshDisplayCnt=0 THEN (* BackSpace *)
IF Down THEN
Down := FALSE;
Scroll := TRUE;
ELSE
Scroll := NOT(Scroll);
END;
END; |
4DH: i:=1; IF Alt THEN i:=NumLines END; (* Down *)
WHILE i#0 DO
IF ScrollDown(NOT(Shift),MyFile#NIL) THEN
Close(MyFile);
MyFile := NIL;
END;
IF RefreshDisplayCnt#0 THEN DEC(RefreshDisplayCnt) END;
DEC(i);
END;
Scroll := FALSE; |
4CH: i:=1; IF Alt THEN i:=NumLines END; (* Up *)
WHILE i#0 DO
IF RefreshDisplayCnt=0 THEN
ScrollUp(NOT(Shift));
Scroll := FALSE;
END;
DEC(i);
END; |
44H: IF ScrollDown(FALSE,MyFile#NIL) THEN (* CR *)
Close(MyFile);
MyFile := NIL;
END;
IF RefreshDisplayCnt#0 THEN DEC(RefreshDisplayCnt) END;
Scroll := FALSE; |
23H: TopLine := FirstLine; (* F *)
BottomLine := FirstLine;
ClearBitMaps();
RefreshDisplayCnt := NumLines-2;
AddBottomLine(BottomLine,FALSE);
Scroll := TRUE;
Down := TRUE; |
28H: WHILE BottomLine^.next#NIL DO (* L *)
BottomLine := BottomLine^.next;
END;
i:=1;
WHILE (i<NumLines) AND (BottomLine^.prev#NIL) DO
BottomLine := BottomLine^.prev;
INC(i);
END;
RefreshDisplayCnt := NumLines-2;
TopLine := BottomLine;
ClearBitMaps();
AddBottomLine(BottomLine,FALSE);
Scroll := TRUE; Down := TRUE; |
5FH,25H: ClearBitMaps();
Write(" MuchMore");
Write(" =============="); Write("");
Write(" Available Commands:"); Write("");
Write(" Space: Start / Stop Scrolling. Quit at end of File."); Write("");
Write(" BackSpace: Start / Stop Scrolling backwards."); Write("");
Write(" Up/Down: Scroll quick one Line up or down."); Write("");
Write(" Shift & Up/Down: Scroll one Line up or down."); Write("");
Write(" Alt & Up/Down: Scroll one Page up or down."); Write("");
Write(" F: Jump to first Page."); Write("");
Write(" L: Jump to last (loaded) Page."); Write("");
Write(" HELP, H: Show Commands."); Write("");
Write(" ESC, Q, X: Quit."); Write("");
Write(" © 1988 Fridtjof Siebert, Nobileweg 67, D-7000-Stuttgart-40");
IF NOT(NTSC()) THEN
FOR i:=0 TO 6 DO Write(""); END;
END;
LOOP
WaitPort(Window^.userPort);
MyMsgPtr := ADDRESS(GetMsg(Window^.userPort));
IF MyMsgPtr^.code<128 THEN EXIT END;
ReplyMsg(MyMsgPtr);
END;
ReplyMsg(MyMsgPtr);
BottomLine := TopLine;
RefreshDisplayCnt := NumLines - 2;
ClearBitMaps();
AddBottomLine(BottomLine,FALSE);
Scroll := TRUE; Down := TRUE; |
10H,45H,32H: EXIT; | (* ESC, Q, X *)
ELSE
END; (* CASE code OF *)
END; (* IF class=IDCMPFlagSet{rawKey} THEN *)
END; (* WITH MyMsg DO *)
END; (* IF MyMsgPtr#NIl THEN *)
END; (* LOOP *)
END; (* IF NumArgs()=0 THEN ELSE *)
END MuchMore.